﻿using EntityFramework.Extensions;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Linq.Expressions;

namespace HobSoft.SoccerBet2014.Domain.Implementation
{
    using Core;
    using Models.Core;
    using SoccerBet2014.Common.DB.Queryable;
    public abstract class ReadWriteSqlEntRepository<T> : ReadonlySqlEntRepository<T>, IReadWriteRepository<T>
         where T : class, IModel
    {
        public ReadWriteSqlEntRepository(DbContext dbContex)
            : base(dbContex)
        {

        }

        public virtual T AddOrUpdate(T model)
        {
            if (model == null)
                return null;

            return DbSet.AddOrUpdate(model);
        }

        public virtual int AddOrUpdate(IList<T> models)
        {
            if (models == null)
                throw new ArgumentNullException("models", "need models.");
            if (!models.Any()) return 0;

            return DbSet.AddOrUpdate(models);
        }

        public virtual bool Delete(T model)
        {
            DbContext.Entry<T>(model).State = EntityState.Deleted;
            var result = DbContext.SaveChanges();
            return result > 0;
        }

        public virtual bool Delete(params object[] ids)
        {
            if (ids.Length == 0) return false;
            T model = DbSet.Find(ids);
            if (model == null) return false;
            DbContext.Entry<T>(model).State = EntityState.Deleted;
            var result = DbContext.SaveChanges();
            return result > 0;
        }

        public virtual int DeleteMany(Expression<Func<T, bool>> predicate)
        {
            if (predicate == null)
                throw new ArgumentNullException("predicate", "need predicate.");

            return DbSet.Where(predicate).Delete();
        }

        public virtual int Update(Expression<Func<T, bool>> predicate, Expression<Func<T, T>> updateExpression)
        {
            if (predicate == null)
                throw new ArgumentNullException("predicate", "need predicate.");
            if (updateExpression == null)
                throw new ArgumentNullException("updateExpression", "need updateExpression.");

            return DbSet.Where(predicate).Update(updateExpression);
        }
    }
}
